﻿using AutoMapper;
using GuanYijia.Application.IntPut;
using GuanYijia.Application.OutPut;
using GuanYijia.DoMain;
using GuanYijia.DoMain.PageDto;
using GuanYijia.EntityFarmeworkCore;
using GuanYijia.Repository;
using Microsoft.AspNetCore.Authorization;
using Microsoft.AspNetCore.Mvc;
using Microsoft.EntityFrameworkCore;
using MySqlConnector;
using NPOI.OpenXmlFormats.Wordprocessing;
using NPOI.POIFS.Crypt.Dsig;
using Org.BouncyCastle.Asn1.Ocsp;
using Panda.DynamicWebApi;
using Panda.DynamicWebApi.Attributes;
using System;
using System.Collections.Generic;
using System.Data;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Transactions;

namespace GuanYijia.Application.ProductionManagement
{
    [DynamicWebApi]
    [ApiExplorerSettings(GroupName = "v1")]
    [Authorize]
    public class ProductionDataService : IDynamicWebApi
    {
        private readonly IBaseRepository<ProductInfo> _productInfoRepository;
        private readonly IBaseRepository<Product_Current_Stock> _currentstockRepository;
        private readonly IBaseRepository<Product_Price> _priceRepository;
        private readonly IBaseRepository<MaterialCategory> _categoryRepository;
        private readonly IBaseRepository<ProductionTaskHead> _taskheadRepository;
        private readonly IBaseRepository<ProductionTaskItem> _taskitemRepository;

        private readonly IBaseRepository<MaterialNeedModel> _materialNeedModelRepository;
        private readonly GuanYiJiaDbContext context;
        private readonly IMapper mapper;
        public ProductionDataService(IBaseRepository<ProductInfo> productInfoRepository, IBaseRepository<Product_Current_Stock> currentstockRepository, IBaseRepository<Product_Price> priceRepository, IBaseRepository<MaterialCategory> categoryRepository, GuanYiJiaDbContext context, IMapper mapper, IBaseRepository<MaterialNeedModel> materialNeedModelRepository, IBaseRepository<ProductionTaskHead> taskheadRepository, IBaseRepository<ProductionTaskItem> taskitemRepository)
        {
            _productInfoRepository = productInfoRepository;
            _currentstockRepository = currentstockRepository;
            _priceRepository = priceRepository;
            _categoryRepository = categoryRepository;
            this.context = context;
            this.mapper = mapper;
            _materialNeedModelRepository = materialNeedModelRepository;
            _taskheadRepository = taskheadRepository;
            _taskitemRepository = taskitemRepository;
        }
        //var redisKey = "GetProductionBowShow_key";
        //// 尝试从Redis获取数据
        //var productionBowShowValue = RedisHelper.Get<List<ProductListDto>>(redisKey);
        //if (productionBowShowValue == null || !productionBowShowValue.Any())
        //{
        //    // 从数据库查询
        //    productionBowShowValue = (from a in _productInfoRepository.GetQueryable(tracking: false)
        //                              join b in _currentstockRepository.GetQueryable(tracking: false) on a.productid equals b.product_id
        //                              join c in _priceRepository.GetQueryable(tracking: false) on a.productid equals c.productid
        //                              join e in _categoryRepository.GetQueryable(tracking: false) on a.category_id equals e.category_id
        //                              select new ProductListDto
        //                              {
        //                                  productid = a.productid,
        //                                  bar_code = c.bar_code,
        //                                  product_name = a.product_name,
        //                                  category_id = a.category_id,
        //                                  standard = a.standard,
        //                                  model = a.model,
        //                                  color = a.color,
        //                                  category_name = e.name,
        //                                  parent_id = e.parent_id,
        //                                  unit = a.unit,
        //                                  mfrs = a.mfrs,
        //                                  current_number = b.current_number,
        //                                  purchase_decimal = c.purchase_decimal,
        //                                  commodity_decimal = c.commodity_decimal,
        //                                  wholesale_decimal = c.wholesale_decimal,
        //                                  low_decimal = c.low_decimal,
        //                                  enabled = a.enabled,
        //                                  enable_serial_number = a.enable_serial_number,
        //                                  safety_stock = a.safety_stock,
        //                                  remark = a.remark
        //                              }).ToList();
        //    var hours = new Random().Next(10, 10);
        //    // 可选择将查询结果缓存到Redis
        //    RedisHelper.Set(redisKey, productionBowShowValue, TimeSpan.FromHours(hours));
        //}

        // 创建查询


        /// <summary>
        /// 商品信息表的显示查询
        /// </summary>
        /// <param name="request"></param>
        /// <returns></returns>
        /// <exception cref="Exception"></exception>
        [AllowAnonymous]
        [HttpPost]
        public async Task<PageResultDto<ProductListDto>> GetProducts(ProductionBOMListIntPut request)
        {
            var list = new PageResultDto<ProductListDto> { Data = new List<ProductListDto>() };

            var pageIndexParam = new MySqlParameter("@pageIndex", request.PageIndex);
            var pageSizeParam = new MySqlParameter("@pageSize", request.PageSize);
            var nameParam = new MySqlParameter("@name", string.IsNullOrWhiteSpace(request.name) ? (object)DBNull.Value : request.name);
            var categoryIdParam = new MySqlParameter("@categoryid", request.categoryid.HasValue ? (object)request.categoryid.Value : DBNull.Value);
            try
            { 
                // 使用原始 SQL 查询获取 DTO
                var result = await context.Set<ProductListDto>()
                    .FromSqlRaw("CALL GetProducts(@pageIndex, @pageSize, @name, @categoryid)",
                                 pageIndexParam, pageSizeParam, nameParam, categoryIdParam)
                    .ToListAsync();
                // 设置返回的数据
                list.Data = result;
            }
            catch (Exception ex)
            {
                // 处理异常，可以记录日志或返回特定的错误信息
                throw new Exception("An error occurred while retrieving products.", ex);
            }
            return list;
        }
        [AllowAnonymous]
        [HttpPost]
        public async Task<PageResultDto<ProductListDto>> MaterialNeedByIdList(MaterialNeedByIdInput request)
        {
            var list = new PageResultDto<ProductListDto> { Data = new List<ProductListDto>() };

            var pageIndexParam = new MySqlParameter("@pageIndex", request.PageIndex);
            var pageSizeParam = new MySqlParameter("@pageSize", request.PageSize);
            var productIdParam = new MySqlParameter("@productid", request.productid.HasValue ? (object)request.productid.Value : DBNull.Value);

            try
            {
                // 使用原始 SQL 查询获取 DTO
                var result = await context.Set<ProductListDto>()
                    .FromSqlRaw("CALL MaterialNeedById(@pageIndex, @pageSize, @productid)",
                                 pageIndexParam, pageSizeParam, productIdParam)
                    .ToListAsync();

                // 设置返回的数据
                list.Data = result;
            }
            catch (Exception ex)
            {
                // 处理异常，可以记录日志或返回特定的错误信息
                throw new Exception("An error occurred while retrieving products.", ex);
            }

            return list;
        }
        [AllowAnonymous]
        [HttpPost]
        public async Task<int> AddMaterialNeed(AddMaterialNeedInPut AddMaterialNeed)
        {
            var result = mapper.Map<MaterialNeedModel>(AddMaterialNeed);
            var index = 0;
            index += await _materialNeedModelRepository.InsertAsync(result);
            return index;
        }
        //第二步物料表的显示
        [AllowAnonymous]
        [HttpPost]
        public async Task<LogListOutPut> MaterialNeedShow(MaterialNeedHShowInPut materialneedshow)
        {
            LogListOutPut logListOutPut = new LogListOutPut();

            var result = _materialNeedModelRepository.GetQueryable(tracking: false).Where(d => d.productid == materialneedshow.productionid);
            logListOutPut.pageTotal = result.Count();
            logListOutPut.pageCount = (int)Math.Ceiling(result.Count() * 1.0 / materialneedshow.PageSize);
            logListOutPut.Data = result.OrderByDescending(d => d.MaterialNeedId).Skip((materialneedshow.PageIndex - 1) * materialneedshow.PageSize).Take(materialneedshow.PageSize);
            return logListOutPut;

        }

        [AllowAnonymous]
        [HttpGet]
        public async Task<LogListOutPut> ShowProductiveTask(MaterialNeedHShowInPut materialneedshow)
        {
            LogListOutPut logListOutPut = new LogListOutPut();

            var result = _materialNeedModelRepository.GetQueryable(tracking: false).Where(d => d.productid == materialneedshow.productionid);
            logListOutPut.pageTotal = result.Count();
            logListOutPut.pageCount = (int)Math.Ceiling(result.Count() * 1.0 / materialneedshow.PageSize);
            logListOutPut.Data = result.OrderByDescending(d => d.MaterialNeedId).Skip((materialneedshow.PageIndex - 1) * materialneedshow.PageSize).Take(materialneedshow.PageSize);
            return logListOutPut;

        }


        /// <summary>
        /// 生产任务添加
        /// </summary>
        /// <param name="info"></param>
        /// <returns></returns>
        [AllowAnonymous]
        [HttpPost]
        public async Task<ResponseModelDto> AddProductiveTask(AddProductionTaskHeadDto info)
        {
            var res = new ResponseModelDto();

            // 创建事务
            using (var transaction = new TransactionScope(TransactionScopeAsyncFlowOption.Enabled))
            {
                try
                {
                    var time = DateTime.Now;

                    #region 生产任务主表添加数据
                    ProductionTaskHead head = new ProductionTaskHead();
                    head.head_no = info.head_no;
                    head.product_id = info.product_id;
                    head.order_quantity = info.order_quantity;
                    head.production_quantity = info.production_quantity;
                    head.bom_quantity = info.bom_quantity;
                    head.bom_allPrice = info.bom_allPrice;
                    head.finish_date = info.finish_date;
                    head.remark = info.remark;
                    await _taskheadRepository.InsertAsync(head);
                    #endregion

                    #region 生产任务BOM表添加数据
                    List<ProductionTaskItem> itemlist = new List<ProductionTaskItem>();
                    foreach (var item in info.items)
                    {
                        ProductionTaskItem items = new ProductionTaskItem();
                        items.head_id = head.head_id;
                        items.product_id = item.product_id;
                        items.oper_number = item.oper_number;
                        items.unit_price = item.unit_price;
                        items.all_price = item.all_price;
                        items.remark = item.remark;
                        itemlist.Add(items);
                    }
                    await _taskitemRepository.InsertRangeAsync(itemlist);
                    #endregion

                    #region 调出BOM的库存修改数量
                    var productIds = info.items.Select(p => p.product_id);
                    var currt = _currentstockRepository.GetQueryable().Where(p => productIds.Contains(p.product_id)).ToList();
                    currt.ForEach(p =>
                    {
                        var itemsModel = info.items.FirstOrDefault(a => a.product_id == p.product_id);
                        if (itemsModel == null) // 如果为null则表示有系统内部错误
                        {
                            throw new Exception("系统错误，找不到编码" + p.currentid + "的商品");
                        }
                        p.current_number -= itemsModel.oper_number;
                    });
                    await _currentstockRepository.UpdateRangeAsync(currt);
                    #endregion

                    // 提交事务
                    transaction.Complete();

                    res.Code = 1;
                    res.Message = "操作成功";
                }
                catch (Exception ex)
                {
                    // 捕获异常，返回失败消息
                    res.Code = 0;
                    res.Message = $"操作失败: {ex.Message}";
                }
            }

            await SendNew.SimpleSendMsgAsync(info);

            return res;

        }

        /// <summary>
        /// 生产任务显示
        /// </summary>
        /// <returns></returns>
        [AllowAnonymous]
        public ResponseDto<List<ProductiveTaskHeadInfo>> GetProductiveTask()
        {
            ResponseDto<List<ProductiveTaskHeadInfo>> res = new ResponseDto<List<ProductiveTaskHeadInfo>>()
            {
                Code = 200,
                Message = "生产任务显示",
                Data = new List<ProductiveTaskHeadInfo>()
            };
            var list = from a in _productInfoRepository.GetQueryable(false)
                       join b in _taskheadRepository.GetQueryable(false) on a.productid equals b.product_id
                       join c in _priceRepository.GetQueryable(false) on a.productid equals c.productid
                       select new ProductiveTaskHeadInfo()
                       {
                           head_id = b.head_id,
                           head_no = b.head_no,
                           product_id = a.productid,
                           product_code = c.bar_code,
                           product_name = a.product_name,
                           product_standard = a.standard,
                           product_model = a.model,
                           order_quantity = b.order_quantity,
                           production_quantity = b.production_quantity,
                           bom_quantity = b.bom_quantity,
                           bom_allPrice = b.bom_allPrice,
                           finish_date = b.finish_date,
                           remark = b.remark,
                           user_id = b.user_id,
                           create_date = b.create_date,
                           statues = b.statues,
                           ItemsInfo = new List<ProductiveTaskItemsInfo>()
                       };
            res.Data = list.ToList();
            foreach (var item in res.Data)
            {
                var itemlist = from a in _productInfoRepository.GetQueryable(false)
                                 join b in _taskitemRepository.GetQueryable(false)
                                 on a.productid equals b.product_id
                                 join c in _priceRepository.GetQueryable(false)
                                 on a.productid equals c.productid
                                 join d in _currentstockRepository.GetQueryable(false)
                                 on a.productid equals d.product_id
                                 where b.head_id == item.head_id
                                 select new ProductiveTaskItemsInfo()
                                 {
                                     taskItemId = b.taskItemId,
                                     head_id = item.head_id,
                                     product_id = a.productid,
                                     product_code = c.bar_code,
                                     product_name = a.product_name,
                                     product_standard = a.standard,
                                     product_model = a.model,
                                     product_unit = a.unit,
                                     current_number = d.current_number,
                                     oper_number = b.oper_number,
                                     unit_price = b.unit_price,
                                     all_price = b.all_price,
                                     remark = b.remark
                                 };
                item.ItemsInfo = itemlist.ToList();
            }
          
            return res;
        }

    }
}
